package com.xiaoma.tpo.webservice;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xiaoma.tpo.domain.StGroup;
import com.xiaoma.tpo.domain.StPlan;
import com.xiaoma.tpo.domain.StScore;
import com.xiaoma.tpo.domain.StSentence;
import com.xiaoma.tpo.domain.User;
import com.xiaoma.tpo.dto.StGroupVo;
import com.xiaoma.tpo.dto.StPlanVo;
import com.xiaoma.tpo.service.SentenceService;
import com.xiaoma.tpo.service.UserService;
import com.xiaoma.tpo.utils.TPOUtils;

@Controller
@RequestMapping("/service/sentence")
public class SentenceWS {
    private static Logger LOG = LoggerFactory.getLogger(SentenceWS.class);

    @Autowired
    private SentenceService sentenceService;
    @Autowired
    private UserService userService;
    
    @RequestMapping(value = "/plans", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> findAllPlans(){
        List<StPlan> sentencePlans = sentenceService.findAllPlans();
        List<StPlanVo> sentencePlanVos = new ArrayList<StPlanVo>(sentencePlans.size());
        for (StPlan plan: sentencePlans) {
            StPlanVo planVo = new StPlanVo();
            planVo.setId(plan.getId());
            planVo.setName(plan.getName());
            planVo.setPlanNo(plan.getPlanNo());
            int groupCount = sentenceService.findGroupCountByPlanId(plan.getId());
            planVo.setGroupCount(groupCount);
            sentencePlanVos.add(planVo);
        }
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("sentencePlans", sentencePlanVos);
        return result;
    }
    
    @RequestMapping(value = "/plans/{planId}/groups", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> findGroupsByPlanId(@PathVariable Integer planId){
        List<StGroup> sentenceGroups = sentenceService.findGroupsByPlanId(planId);
        List<StGroupVo> sentenceGroupVos = new ArrayList<StGroupVo>(sentenceGroups.size());
        for (StGroup group : sentenceGroups) {
            StGroupVo groupVo = new StGroupVo();
            groupVo.setId(group.getId());
            groupVo.setAudioZip(group.getAudioZip());
            groupVo.setGroupNo(group.getGroupNo());
            groupVo.setName(group.getName());
            groupVo.setPlanId(group.getStPlanId());
            int sentenceCount = sentenceService.findSentenceCountByGroupId(group.getId());
            groupVo.setSentenceCount(sentenceCount);
            sentenceGroupVos.add(groupVo);
        }
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("sentenceGroups", sentenceGroupVos);
        return result;
    }
    
    @RequestMapping(value = "/groups/{groupId}/sentences", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> findSentencesByGroupId(@PathVariable Integer groupId){
        List<StSentence> sentences = sentenceService.findSentencesByGroupId(groupId);
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("sentences", sentences);
        return result;
    }
    
    @RequestMapping(value = "/score", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> submitScore(@RequestHeader String token, @RequestBody Map<String, Object> map) {
        Map<String, Object> result = new HashMap<String, Object>();
        Integer planId = (Integer)map.get("planId");
        Integer groupId = (Integer)map.get("groupId");
        Integer score = (Integer)map.get("score");
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.over7days(new Date(), user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        try{
            StScore stScore = sentenceService.findScoreByPlanIdAndGroupIdAndUserId(planId, groupId, user.getId());
            if (stScore == null) {
                stScore = new StScore();
                stScore.setScore(score);
                stScore.setUserId(user.getId());
                stScore.setStGroupId(groupId);
                stScore.setStPlanId(planId);
                stScore.setCreatedAt(new Date());
                sentenceService.saveScore(stScore);
            } else {
                stScore.setScore(score);
                sentenceService.updateScore(stScore);
            }
            int ranking = sentenceService.getRanking(stScore, planId, groupId);
            if (!TPOUtils.isAnonymous(user)) {//如果不是匿名用户，则更新访问时间
                userService.updateVisitTime(user);
            }
            result.put("ranking", ranking);
        } catch(Exception e) {
            result.put("status", 0);
            result.put("message", e);
        }
        return result;
    }
    
    @RequestMapping(value = "/score/ranking", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getRanking(@RequestHeader String token, Integer planId, Integer groupId) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.over7days(new Date(), user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        
        StScore score = sentenceService.findScoreByPlanIdAndGroupIdAndUserId(planId, groupId, user.getId());
        if(score == null) {
            result.put("ranking", null);
        } else {
            int ranking = sentenceService.getRanking(score, planId, groupId);
            result.put("ranking", ranking);
        }
        if (!TPOUtils.isAnonymous(user)) {//如果不是匿名用户，则更新访问时间
            userService.updateVisitTime(user);
        }
        
        return result;
    }
}
